#include "segment.h"
#include "STC89C5xRC.H"
#include "task.h"

#if (SEGMENT_TASK|SEGMENT_INTERRUPT_TASK)

sbit segment_du = P2 ^ 0;
sbit segment_we = P2 ^ 1;
#define segment_data_port P0

#define SEGMENT_BLANKING_TIME 50                                                                                                           /* !> us */
uint8_t code segment_du_data[17] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x80}; /* !> 0-.  save to ROM */
uint8_t code segment_we_bit[8] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};                                                         /* !> segment_bit  save to ROM */

static volatile uint8_t segment_dis_buffer[8];

/**
 * @brief segment_blanking
 *
 */
static void segment_blanking(void)
{
    segment_data_port = 0;
    segment_du = 1;
    segment_du = 0;
}

/**
 * @brief segment_display_one_bit
 *
 * @param dis_bit 0-7
 * @param dis_data 0-15
 */
static void segment_display_one_bit(uint8_t dis_bit, uint8_t dis_data)
{
    /* set segment bit_0 start */
    segment_data_port = segment_we_bit[dis_bit];
    segment_we = 1;
    segment_we = 0;
    /* set segment bit end */

    /* set segment bit_0 data start */
    segment_data_port = dis_data;
    segment_du = 1;
    segment_du = 0;
    /* set segment data end */
}

/**
 * @brief segment_display_one_bit
 *
 * @param dis_bit 0-7
 * @param dis_data 0-15
 */
static void segment_display_all_bit(uint8_t dis_data)
{
    /* set segment bit_0 start */
    segment_data_port = 0x00;
    segment_we = 1;
    segment_we = 0;
    /* set segment bit end */

    /* set segment bit_0 data start */
    segment_data_port = dis_data;
    segment_du = 1;
    segment_du = 0;
    /* set segment data end */
}

/**
 * @brief segment_display_num
 *
 * @param dis_bit 0-7
 * @param dis_data 0-9
 */
void segment_display_one_num(uint8_t dis_bit, uint8_t dis_data)
{
    switch (dis_bit)
    {
    case 0:
        segment_display_one_bit(0, segment_du_data[dis_data]);
        break;
    case 1:
        segment_display_one_bit(1, segment_du_data[dis_data]);
        break;
    case 2:
        segment_display_one_bit(2, segment_du_data[dis_data]);
        break;
    case 3:
        segment_display_one_bit(3, segment_du_data[dis_data]);
        break;
    case 4:
        segment_display_one_bit(4, segment_du_data[dis_data]);
        break;
    case 5:
        segment_display_one_bit(5, segment_du_data[dis_data]);
        break;
    case 6:
        segment_display_one_bit(6, segment_du_data[dis_data]);
        break;
    case 7:
        segment_display_one_bit(7, segment_du_data[dis_data]);
        break;
    default:
        break;
    }
    segment_blanking(); /* segment balnking */
}

/**
 * @brief segment_calculate_dis_data
 *
 * @param dis_data
 */
void segment_calculate_dis_data(uint16_t dis_data)
{
}

/**
 * @brief segment_refresh_interrupt
 *
 */
void segment_refresh_interrupt(void)
{
    segment_display_one_num(0, 0);
    segment_display_one_num(1, 1);
    segment_display_one_num(2, 2);
    segment_display_one_num(3, 3);
    segment_display_one_num(4, 4);
    segment_display_one_num(5, 5);
    segment_display_one_num(6, 6);
    segment_display_one_num(7, 16);
}

/**
 * @brief segment_test_proc
 *
 */
void segment_test_proc(void)
{
    uint8_t i, j, dis_buf;
    for (i = 0; i < 8; i++)
    {
        dis_buf = 0x01;
        for (j = 0; j < 8; j++)
        {
            segment_display_one_bit(i, dis_buf);
            delay_ms(10);
            dis_buf = dis_buf << 1;
        }
    }

    for (i = 0; i < 4; i++)
    {
        segment_display_all_bit(0xFF);
        delay_ms(20);
        segment_display_all_bit(0x00);
        delay_ms(20);
    }
}

#endif